---
title: "Suspend & Resume Workflows (vNext) | Human-in-the-Loop | Kastrax Docs"
description: "Suspend and resume in Kastrax vNext workflows allows you to pause execution while waiting for external input or resources."
---

# Suspend and Resume in Workflows

Complex workflows often need to pause execution while waiting for external input or resources.

Kastrax's suspend and resume features let you pause workflow execution at any step, persist the workflow snapshot to storage, and resume execution from the saved snapshot when ready.
This entire process is automatically managed by Kastrax. No config needed, or manual step required from the user.

Storing the workflow snapshot to storage (LibSQL by default) means that the workflow state is permanently preserved across sessions, deployments, and server restarts. This persistence is crucial for workflows that might remain suspended for minutes, hours, or even days while waiting for external input or resources.

## When to Use Suspend/Resume

Common scenarios for suspending workflows include:

- Waiting for human approval or input
- Pausing until external API resources become available
- Collecting additional data needed for later steps
- Rate limiting or throttling expensive operations
- Handling event-driven processes with external triggers

## How to suspend a step

```typescript
const humanInputStep = createStep({
  id: "human-input",
  inputSchema: z.object({
    suggestions: z.array(z.string()),
    vacationDescription: z.string(),
  }),
  resumeSchema: z.object({
    selection: z.string(),
  }),
  suspendSchema: z.object({}),
  outputSchema: z.object({
    selection: z.string().describe("The selection of the user"),
    vacationDescription: z.string(),
  }),
  execute: async ({ inputData, resumeData, suspend }) => {
    if (!resumeData?.selection) {
      await suspend({});
      return {
        selection: "",
        vacationDescription: inputData?.vacationDescription,
      };
    }
    return {
      selection: resumeData.selection,
      vacationDescription: inputData?.vacationDescription,
    };
  },
});
```

## How to resume step execution

### Identifying suspended state

When running a workflow, its state can be one of the following:

- `running` - The workflow is currently running
- `suspended` - The workflow is suspended
- `success` - The workflow has completed
- `failed` - The workflow has failed

When the state is `suspended`, you can identify any and all steps that have been suspended by looking at the `suspended` property of the workflow.

```typescript
const run = counterWorkflow.createRun();
const result = await run.start({ inputData: { startValue: 0 } });

if (result.status === "suspended") {
  const resumedResults = await run.resume({
    step: result.suspended[0],
    resumeData: { newValue: 0 },
  });
}
```

In this case, the logic resumes whatever is the first step reported as suspended.

The `suspended` property is of type `string[][]`, where every array is a path to a step that has been suspended, the first element being the step id on the main workflow. If that step is a workflow itself, the second element is the step id on the nested workflow that was suspended, unless it is a workflow itself, in which case the third element is the step id on the nested workflow that was suspended, and so on.

### Resume

```typescript
// After getting user input
const result = await workflowRun.resume({
  step: userInputStep, // or 'myStepId' as a string
  resumeData: {
    userSelection: "User's choice",
  },
});
```

To resume a suspended nested workflow:

```typescript
const result = await workflowRun.resume({
  step: [nestedWorkflow, userInputStep], // or ['nestedWorkflowId', 'myStepId'] as a string array
  resumeData: {
    userSelection: "User's choice",
  },
});
```
